package com.mt.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mt.RedisUtils;
import com.mt.constants.SYS;
import com.mt.enums.LikeStatus;
import com.mt.enums.Status;
import com.mt.exception.GlobalException;
import com.mt.mapper.FilmCommentMapper;
import com.mt.utils.RedisKeyGenerator;
import com.mt.mapper.CommentLikeMapper;
import com.mt.pojo.CommentLike;
import com.mt.service.CommentLikeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @author Wang
 * @Description 评论点赞Service
 * @date 2020/12/4-11:25
 */
@Service
public class CommentLikeServiceImpl extends ServiceImpl<CommentLikeMapper, CommentLike> implements CommentLikeService {
    @Resource
    CommentLikeMapper commentLikeMapper;

    @Resource
    FilmCommentMapper commentMapper;

    @Resource
    RedisUtils redisUtils;

    /**
     * 批量插入点赞信息入库
     */
    @Override
    public boolean addLikeList(List<CommentLike> list) {
        if (list == null || list.isEmpty()) {
            throw new GlobalException("点赞缓存列表为空,无法持久化");
        }
        return commentLikeMapper.insertLikeList(list);
    }

    /**
     * 批量修改变化的点赞信息
     */
    @Override
    public boolean modifyLikeList(List<CommentLike> list) {
        if (list == null || list.isEmpty()) {
            throw new GlobalException("点赞缓存列表为空,无法持久化");
        }
        return commentLikeMapper.modifyLikeList(list);
    }


    /**
     * 定时任务: 批量存储点赞信息入库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveLikeList2Db(List<CommentLike> list) {
        List<CommentLike> updateList = CollUtil.newArrayList();
        List<CommentLike> insertList = CollUtil.newArrayList();
        for (CommentLike like : list) {
            CommentLike commentLike = commentLikeMapper.selectOne(Wrappers.<CommentLike>lambdaQuery()
                    .eq(CommentLike::getCommentId, like.getCommentId())
                    .eq(CommentLike::getUserId, like.getUserId()));
            if (commentLike != null) {
                updateList.add(like);
            } else {
                insertList.add(like);
            }
        }
        boolean addLikeList = this.addLikeList(insertList);
        boolean modifLikeList = this.modifyLikeList(updateList);
        if (addLikeList && modifLikeList) {
            for (CommentLike like : list) {
                String key = RedisKeyGenerator.getLikeKey(like.getUserId(), like.getCommentId());
                log.debug("清除点赞缓存COMMENT_LIKE." + key);
                redisUtils.hdel(SYS.COMMENT_LIKE, key);
            }
        } else {
            throw new GlobalException(Status.ERROR, "点赞信息缓存入库失败");
        }

        return true;
    }

    /**
     * 定时任务: 统计点赞数量入库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean countLikeTotal(Map<Integer, Integer> likeMap) {
        return commentMapper.batchUpdateCommentLikeNum(likeMap);
    }

    /**
     * 点赞信息加入缓存
     */
    @Override
    public boolean addLike2Redis(String userId, int commentId, int likeStatus) {
        String itemKey = RedisKeyGenerator.getLikeKey(userId, commentId);
        return redisUtils.hset(SYS.COMMENT_LIKE, itemKey, likeStatus);
    }

    /**
     * 用户查看评论时,获得点赞的状态
     */
    @Override
    public int getCommentLikeStatus(String userId, int commentId) {
        String itemKey = RedisKeyGenerator.getLikeKey(userId, commentId);
        if (redisUtils.hexists(SYS.COMMENT_LIKE, itemKey)) {
            System.out.println((int) redisUtils.hget(SYS.COMMENT_LIKE, itemKey));
            return (int) redisUtils.hget(SYS.COMMENT_LIKE, itemKey);
        }
        CommentLike like = commentLikeMapper.selectOne(Wrappers.<CommentLike>lambdaQuery().eq(CommentLike::getCommentId, commentId)
                .eq(CommentLike::getUserId, userId));
        //遗漏逻辑! 用户没有过操作时 like可能为null
        if (like == null) {
            return LikeStatus.UNLIKE.getCode();
        }
        return (like.getLikeStatus().equals(LikeStatus.LIKE.getCode())) ? LikeStatus.LIKE.getCode() : LikeStatus.UNLIKE.getCode();
    }
}
